package heap;

import global.*;

import java.io.*;

import bufmgr.BufMgrException;
import bufmgr.BufferPoolExceededException;
import bufmgr.HashOperationException;
import bufmgr.InvalidFrameNumberException;
import bufmgr.PageNotReadException;
import bufmgr.PagePinnedException;
import bufmgr.PageUnpinnedException;
import bufmgr.ReplacerException;

import diskmgr.Page;



public class Scan extends Object implements GlobalConst {
	
	String hFName;
	PageId firstPageId;
	Page page;
	PageId curPageId;
	HFPage curPage;
	RID curRid;
	
	
	public Scan(Heapfile hf) 
			throws HFDiskMgrException, HFException, HFBufMgrException
			
	{
		
		if(hf != null){
			//hFName = hf.name;
			try {
				
				curPageId = SystemDefs.JavabaseDB.get_file_entry(hf.name);
				page = new Page();
				

			} catch (Exception e) {
				throw new HFDiskMgrException(e, "Heap File Exception: can't get the first page.");
			} 

			

			curRid = null;
			firstPageId = new PageId();
			firstPageId.pid = curPageId.pid;
			
			try {
				SystemDefs.JavabaseBM.pinPage(curPageId, page, false);
			} catch (Exception e) {
				throw new HFBufMgrException(e, "Heap File Buffer Manager Exception");
			}
			curPage = new HFPage(page);			
			

		}else{
			throw new HFException( null, "Heap File Buffer Manager Exception");
		}
	}
	
	public Tuple getNext(RID rid) 
			throws HFBufMgrException
	{
		try{
			
			//SystemDefs.JavabaseBM.pinPage(curPageId, page, false);
			//curPage = new HFPage(page);
			//curPage.init(curPageId, page);
			if(curRid != null){

				while(curPage.nextRecord(curRid) == null){
					PageId nextPageId = curPage.getNextPage();
					
					
					if(firstPageId.pid == nextPageId.pid){

						SystemDefs.JavabaseBM.unpinPage(curPageId, false);
						return null;
					}
					SystemDefs.JavabaseBM.unpinPage(curPageId, false);
					curPageId = nextPageId;
					SystemDefs.JavabaseBM.pinPage(curPageId, page, false);
					curPage = new HFPage(page);
					//curPage.init(curPageId, page);
					if(curPage.firstRecord() != null){
							curRid = null;
							break;
						
					}

					

				}

				if(curRid != null){
					curRid = curPage.nextRecord(curRid);
				}else{
					curRid = curPage.firstRecord();	
				}
				
				
			}
			else{	// first record

				curRid = curPage.firstRecord();	
			}	

			
			Tuple result = curPage.getRecord(curRid);

			rid.copyRid(curRid);
		//	SystemDefs.JavabaseBM.unpinPage(curPageId, false);
			return result;
			
		} catch (Exception e) {
			throw new HFBufMgrException(e, "Heap File Buffer Manager Exception");
		}
		
		
	}

	public void closescan()
	{

		curPageId = null;
		curPage = null;
		curRid = null;

	}
}
